package org.chimi.rr4s.sitemesh;

import java.util.Properties;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

import com.opensymphony.module.sitemesh.Config;
import com.opensymphony.module.sitemesh.Decorator;
import com.opensymphony.module.sitemesh.DecoratorMapper;
import com.opensymphony.module.sitemesh.Page;
import com.opensymphony.module.sitemesh.mapper.AbstractDecoratorMapper;
import com.opensymphony.module.sitemesh.mapper.ConfigLoader;

/**
 * URI 패턴 기반의 매핑 처리를 위한 커스텀 DecoratorMapper
 * 
 * @author 최범균
 * 
 */
public class UriBasedDecoratorMapper extends AbstractDecoratorMapper {

	private ConfigLoader configLoader = null;

	/** Create new ConfigLoader using '/WEB-INF/decorators.xml' file. */
	@Override
	public void init(Config config, Properties properties,
			DecoratorMapper parent) throws InstantiationException {
		super.init(config, properties, parent);
		try {
			String fileName = properties.getProperty("config",
					"/WEB-INF/decorators.xml");
			configLoader = new ConfigLoader(fileName, config);
		} catch (Exception e) {
			throw new InstantiationException(e.toString());
		}
	}

	/**
	 * Retrieve {@link com.opensymphony.module.sitemesh.Decorator} based on
	 * 'pattern' tag.
	 */
	@Override
	public Decorator getDecorator(HttpServletRequest request, Page page) {
		String thisPath = request.getRequestURI();
		String contextPath = request.getContextPath();
		if (thisPath.startsWith(contextPath)) {
			thisPath = thisPath.substring(contextPath.length());
		}
		String name = null;
		try {
			name = configLoader.getMappedName(thisPath);
		} catch (ServletException e) {
			e.printStackTrace();
		}
		Decorator result = getNamedDecorator(request, name);
		return result == null ? super.getDecorator(request, page) : result;
	}

	/**
	 * Retrieve Decorator named in 'name' attribute. Checks the role if
	 * specified.
	 */
	@Override
	public Decorator getNamedDecorator(HttpServletRequest request, String name) {
		Decorator result = null;
		try {
			result = configLoader.getDecoratorByName(name);
		} catch (ServletException e) {
			e.printStackTrace();
		}

		if (result == null
				|| (result.getRole() != null && !request.isUserInRole(result
						.getRole()))) {
			// if the result is null or the user is not in the role
			return super.getNamedDecorator(request, name);
		} else {
			return result;
		}
	}
}
